#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QCloseEvent>
#include <QAbstractSocket>
#include "ui_accelerometerWidgetUI.h"
#include "ui_compassWidgetUI.h"
#include "ui_controlsWidgetUI.h"
#include "ui_gpsWidgetUI.h"
#include "ui_gyroscopeWidgetUI.h"
#include "ui_pressureWidgetUI.h"
#include "ui_ultrasonicSensorsUI.h"
#include <QAbstractItemModel>
#include <QDomDocument>
#include <QModelIndex>


namespace Ui {
class MainWindow;
}
class rpi_control;
class SpinBoxDelegate;
class EightBitSpinBox;
class ComboBoxDelegate;
class DeviceDelegate;
class rpi_sensor_compass;
class rpi_sensor_pressure;
class rpi_sensor_gps;
class rpi_sensor_acc;
class rpi_sensor_gyro;
class rpi_sensor_ultrasonic;
class rpi_control;
class RPIHelicopterClient;
class ControlModel;
class ControlItem;
class QStandardItemModel;

class accelerometerWidget : public QDockWidget , Ui::accelerometerWidgetUI {
    Q_OBJECT
public:
    accelerometerWidget(QObject *parent,rpi_sensor_acc *a);

    ~accelerometerWidget();
private:
    rpi_sensor_acc *acc;
public slots:
    void refreshContent();
};


class gyroscopeWidget : public QDockWidget , Ui::gyroscopeWidgetUI {
    Q_OBJECT
public:
    gyroscopeWidget(QObject *parent,rpi_sensor_gyro *a);

    ~gyroscopeWidget();
private:
    rpi_sensor_gyro *gyro;
public slots:
    void refreshContent();
};


class compassWidget : public QDockWidget , Ui::compassWidgetUI {
    Q_OBJECT
public:
    compassWidget(QObject *parent,rpi_sensor_compass *a);

    ~compassWidget();
private:
    rpi_sensor_compass *compass;
public slots:
    void refreshContent();
};


class pressureWidget : public QDockWidget , Ui::pressureWidgetUI {
    Q_OBJECT
public:
    pressureWidget(QObject *parent,rpi_sensor_pressure *a);

    ~pressureWidget();
private:
    rpi_sensor_pressure *pressure;
public slots:
    void refreshContent();
};

class gpsWidget : public QDockWidget , Ui::gpsWidgetUI {
    Q_OBJECT
public:
    gpsWidget(QObject *parent,rpi_sensor_gps *a);

    ~gpsWidget();
private:
    rpi_sensor_gps *gps;
public slots:
    void refreshContent();
};


class ultrasonicSensoresWidget : public QDockWidget , Ui::ultraSonicSensors {
    Q_OBJECT
public:
    ultrasonicSensoresWidget(QObject *parent,QList<rpi_sensor_ultrasonic*> *l);
    ~ultrasonicSensoresWidget();
private:
    QList<rpi_sensor_ultrasonic*> *sensors;
public slots:
    void refreshContent();
};

class controlsWidget : public QDockWidget , Ui::controlsWidgetUI {
    Q_OBJECT
public:
    enum CONTROL_COLUMNS { COL_TYPE=0,COL_DEVICE, COL_ADDRESS, COL_NODE,COL_VALUE};
    controlsWidget(QObject *parent,QList<rpi_control*> *l);
    ~controlsWidget();
private:
    QList<rpi_control*> *controls;
public slots:
    void refreshContent();
    void ControlChanged(int row, int column);
    void refreshControl(int k);
protected:
    EightBitSpinBox *spinDelegate;
    ComboBoxDelegate *comboTypes;
    DeviceDelegate *comboDevices;
    bool ignoreChanges;


    ControlModel *cModel;
    ControlModel *rModelItem;
    QStandardItemModel *sModel;
    //ControlModel *cm;
public:
signals:
    void controlUpdate(int i);
};

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:

    RPIHelicopterClient *client;
    accelerometerWidget *accelerometerW;
    gyroscopeWidget *gyroscopeW;
    pressureWidget *pressureW;
    controlsWidget *controlsW;
    ultrasonicSensoresWidget *ultrasonicSensoresW;
    compassWidget *compassW;
    gpsWidget *gpsW;

    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    
private:
    Ui::MainWindow *ui;
public slots:
        void connectBtnPressed();
        void saveDockState();
        void loadDockState();
        void closeEvent(QCloseEvent *event);
        void steerTo(int s);
        void setMotorPower(int p);
        void moveForward();
        void moveBackward();
        void setAccXYZT(double *z);

public slots:
        void connectMBtnClicked();
        void disconnectMBtnClicked();
        void configureAccelerometerMBtnClicked();
        void configureGyroscopeMBtnClicked();
        void configureCompassMBtnClicked();
        void configurePressureMBtnClicked();
        void configureGPSMBtnClicked();
        void insertUltrasonicMBtnClicked();
        void insertcontrolMBtnClicked();
        void removeUltrasonicMBtnClicked();
        void removecontrolMBtnClicked();
        void unableToConnect();
        void lostConnection();
        void Connected();
        void socketError(QAbstractSocket::SocketError e);
};


#endif // MAINWINDOW_H
